package com.teapos.service;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import jodd.http.HttpRequest;
import jodd.http.HttpResponse;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.alibaba.fastjson.JSON;
import com.teapos.dao.AdvancePayDao;
import com.teapos.dao.CustomerDao;
import com.teapos.dao.OrderDao;
import com.teapos.dao.ProductDao;
import com.teapos.dao.QRcodeDao;
import com.teapos.enumtype.TradeTypeEnum;
import com.teapos.enumtype.Unit4SaveEnum;
import com.teapos.util.BusinessTool;
import com.teapos.util.Lists;
import com.teapos.util.Maps;
import com.teapos.util.PropUtil;
import com.teapos.util.Tool;

@SuppressWarnings({"rawtypes", "unchecked"})
@Service
public class AdvancePayService {
	
	@Autowired
	private ProductDao productDao;
	@Autowired
	private OrderDao orderDao;
	@Autowired
	private AdvancePayDao advancePayDao;
	@Autowired
	private CustomerDao customerDao;
	@Autowired
	private QRcodeDao qRcodeDao;

	public Map findProductById(String id, int unit) {
		Map map = productDao.findProductById(id);
		if(map!=null) {
			//散装：0  整装：1
			if(unit==1) {
				map.put("price", Tool.toInt(map.get("zjdlj"))/100);
			} else if(unit==2) {
				map.put("price", Tool.toInt(map.get("dpxsj"))/100);
			}
//			String unit = Tool.toString(map.get("unit"));
//			if("片".equals(unit)) map.put("price", Tool.toInt(map.get("dpxsj"))/100);
//			else if("件".equals(unit)) map.put("price", Tool.toInt(map.get("zjdlj"))/100);
		}
		return map;
	}

	@Transactional(rollbackFor=Exception.class, readOnly=false, propagation=Propagation.REQUIRED)
	public void checkAndSaveOrder(Map map) {
		//order:id, order_no, order_date, order_status(0:未撤销1:已撤销), has_save, user_id, user_name, store_id, store_name, 
		//cash_amount, bank_amount, serial_no, vip_amount, vip_no, wipe_amount, sum_amount, pay_amount, sum_buy, sum_save,
		//customer_id, type(1:散客买茶2:会员买茶3:预收款管理4:货品收购5:pad下单)
		String orderId = BusinessTool.generateId();
		String orderNo = BusinessTool.generateOrderNo();
		Map user = (Map)map.get("user");
		Map customer = (Map)map.get("customer");
		Map price = (Map)map.get("price");
		Map order = new Maps().put("id", orderId).put("order_no", orderNo).put("has_save", 0).put("user_id", user.get("id"))
				.put("user_name", user.get("username")).put("store_id", user.get("stid"))
				.put("store_name", user.get("store_name")).put("cash_amount", Tool.toBigDecimal(map.get("cash_amount")))
				.put("bank_amount", Tool.toBigDecimal(map.get("bank_amount"))).put("serial_no", map.get("serial_no"))
				.put("vip_amount", Tool.toBigDecimal(map.get("vip_amount"))).put("vip_no", map.get("vip_no"))
				.put("wipe_amount", Tool.toBigDecimal(map.get("wipe_amount")))
				.put("sum_amount", Tool.toBigDecimal(price.get("sum_price"))).put("sum_buy", Tool.toBigDecimal(map.get("sum_buy")))
				.put("customer_id", customer.get("id")).put("type", TradeTypeEnum.BEFORE.getCode())
				.put("pay_amount", Tool.toBigDecimal(map.get("pay_amount"))).build();
		
		orderDao.saveOrder(order);
		
		//orders_advance
		//#{id}, #{order_id}, #{pay_rate}, #{total_amount}, #{receive_amount}
		//, #{send_status}, ${customer_tel}, now()
		
		Map advance = new Maps().put("id", BusinessTool.generateId()).put("order_id", orderId)
				.put("pay_rate", price.get("sum_rate")).put("total_amount", Tool.toBigDecimal(price.get("sum_price")))
				.put("receive_amount", Tool.toBigDecimal(price.get("real_price"))).put("customer_tel", customer.get("telphone")).build();
		advancePayDao.saveAdvanceOrder(advance);
				
		//orders_advance_product
		//#{item.id}, #{item.order_id}, #{item.product_id},#{item.product_name},#{item.productionyear}, #{item.batch},#{item.unit},
		//#{item.num}, 0, #{item.advance_price}, now()
		
		//orders_advance_pay
		//#{id}, #{order_id}, #{cash_amount}, #{bank_amount}, #{serial_no}
		//, #{vip_amount}, #{vip_no}, #{wipe_amount}, #{sum_amount}, #{pay_amount}, now()
		
		Map pay = new Maps().put("id", BusinessTool.generateId()).put("order_id", orderId)
				.put("cash_amount", Tool.toBigDecimal(map.get("cash_amount")))
				.put("bank_amount", Tool.toBigDecimal(map.get("bank_amount"))).put("serial_no", map.get("serial_no"))
				.put("vip_amount", Tool.toBigDecimal(map.get("vip_amount"))).put("vip_no", map.get("vip_no"))
				.put("wipe_amount", Tool.toBigDecimal(map.get("wipe_amount")))
				.put("sum_amount", Tool.toBigDecimal(price.get("sum_price")))
				.put("pay_amount", Tool.toBigDecimal(map.get("pay_amount")))
				.put("store_id", user.get("stid")).build();
		advancePayDao.saveAdvancePayInfo(pay);
		
		List products = (List) map.get("products");
		Iterator iter = products.iterator();
		List productList = Lists.newArrayList();
		while(iter.hasNext()) {
			Map product = (Map)iter.next();
			int unit = product.get("unit").equals("散装")?0:1;
			Map item = new Maps().put("id", BusinessTool.generateId()).put("order_id", orderId)
					.put("product_id", product.get("product_id")).put("product_name", product.get("product_name"))
					.put("productionyear", product.get("productionyear")).put("batch", product.get("batch"))
					.put("unit", unit).put("num", product.get("num")).put("advance_price", Tool.toBigDecimal(product.get("price"))).build();
			productList.add(item);
			
		}
		advancePayDao.saveAdvanceProducts(productList);
	}

	public Map findAdvanceByOrderId(String id) {
		Map advance = advancePayDao.findAdvanceByOrderId(id);
		BigDecimal totalAmount = Tool.toBigDecimal(advance.get("total_amount"));
		BigDecimal receiveAmount = Tool.toBigDecimal(advance.get("receive_amount"));
		BigDecimal leftAmount = totalAmount.subtract(receiveAmount);
		advance.put("left_amount", leftAmount);
		return advance;
	}
	
	@Transactional(propagation=Propagation.REQUIRED, rollbackFor=Exception.class, readOnly=false)
	public void saveOrderPay(Map map) {
		
		BigDecimal cashAmount = Tool.toBigDecimal(map.get("cash_amount"));
		BigDecimal bankAmount = Tool.toBigDecimal(map.get("bank_amount"));
		BigDecimal vipAmount = Tool.toBigDecimal(map.get("vip_amount"));
		BigDecimal wipeAmount = Tool.toBigDecimal(map.get("wipe_amount"));
		BigDecimal totalAmount = cashAmount.add(bankAmount).add(vipAmount).add(wipeAmount);
		BigDecimal payAmount = cashAmount.add(bankAmount).add(vipAmount);
		BigDecimal sumAmount = Tool.toBigDecimal(map.get("sum_amount"));
		double payRate = totalAmount.divide(sumAmount,2,BigDecimal.ROUND_HALF_DOWN).doubleValue(); 
		
		Map advance = new Maps().put("id", map.get("order_id")).put("total_amount", totalAmount)
				.put("pay_rate", payRate).build();
		advancePayDao.updateAdvanceOrder(advance);
		
		Map pay = new Maps().put("id", BusinessTool.generateId()).put("order_id", map.get("order_id"))
				.put("cash_amount", cashAmount)
				.put("bank_amount", bankAmount).put("serial_no", map.get("serial_no"))
				.put("vip_amount", vipAmount).put("vip_no", map.get("vip_no"))
				.put("wipe_amount", wipeAmount)
				.put("sum_amount", totalAmount)
				.put("pay_amount", payAmount).build();
		advancePayDao.saveAdvancePayInfo(pay);
	}

	public void fullAdvance(String id) {
		advancePayDao.updatePayStatus(id);
	}

	public Map getAdvanceSendData(String orderId, String customerId) {
		Map customer = customerDao.findCustomerById(customerId);
		List products = advancePayDao.findProductsByOrderId(orderId);
		return Maps.newHashMap("customer", customer, "products", products);
	}

	public Map findSendCode(Map map) {
		Map code = advancePayDao.findSendCodeByProductId(map);
		if(code!=null) {
			String unit = Tool.toString(code.get("unit"));
			if("片".equals(unit)) code.put("price", Tool.toInt(code.get("dpxsj"))/100);
			else if("件".equals(unit)) code.put("price", Tool.toInt(code.get("zjdlj"))/100);
		}
		return code;
	}
	
	@Transactional(propagation=Propagation.REQUIRED, readOnly=false, rollbackFor=Exception.class)
	public void advanceSend(Map map) {
		//id,order_id,order_no,qrcode_id,discount,org_price,is_save,product_name,now_price,product_id,unit,create_time
		System.err.println(map);
		String codeJson = Tool.toString(map.get("codes"));
		String orderId = Tool.toString(map.get("orderId"));
		String customerId = Tool.toString(map.get("customerId"));
		Map user = (Map)map.get("user");
		Map order = orderDao.findOrderById(orderId);
		Map customer = customerDao.findCustomerById(customerId);
		List codeList = JSON.parseArray(codeJson);
		Iterator iter = codeList.iterator();
		List items = new ArrayList();
		while(iter.hasNext()) {
			Map item = (Map)iter.next();
			BigDecimal orgPrice = Tool.toBigDecimal(item.get("org_price"));
			BigDecimal nowPrice = Tool.toBigDecimal(item.get("now_price"));
			BigDecimal discount = nowPrice.divide(orgPrice, 2, BigDecimal.ROUND_HALF_DOWN);
			String unit = Tool.toString(item.get("unit"));
			String productId = Tool.toString(item.get("product_id"));
			int unitVal = Unit4SaveEnum.getEnumByName(unit).getCode();
			Map newItem = new Maps().put("id", BusinessTool.generateId()).put("order_id", orderId).put("order_no", order.get("order_no"))
					.put("qrcode_id", item.get("qrcode_id")).put("discount", discount).put("org_price", orgPrice)
					.put("product_name", item.get("product_name")).put("now_price", item.get("now_price"))
					.put("product_id", productId).put("unit", unitVal).build();
			System.err.println(newItem);
			items.add(newItem);
			
			//扣减店面库存
			Map data = Maps.newHashMap(productId, Maps.newHashMap("type", 0, "unit", unit, "customerId", 0, "count", 1));
			
			HttpResponse response = HttpRequest
			        .post(PropUtil.getValueByKey("url.stock"))
			        .form("storeId", user.get("store_id"), "data", JSON.toJSONString(data))
			        .send();
			System.err.println(response.body());
			Map result = JSON.parseObject(response.body());
			String msg = Tool.toString(result.get(productId));
			if("error".equals(msg)) throw new RuntimeException("扣减库存失败！！");
			//增加客户库存
			//...
			//绑定客户和二维码
			qRcodeDao.bindUserCode(Maps.newHashMap("customer_id", customerId, "customer_name", customer.get("name"), 
					"code", item.get("qrcode_id")));
			//对应商品已发货数量+1
			advancePayDao.updateAdvanceProductSendNum(Maps.newHashMap("order_id", orderId, "product_id", productId));
		}
		advancePayDao.saveAdvanceOrderItems(items);
	}

	public Map getOrderDetail(String orderId, String customerId) {
		Map customer = customerDao.findCustomerById(customerId);
		List products = advancePayDao.findProductsByOrderId(orderId);
		Iterator iter = products.iterator();
		Map tempMap = new HashMap();
		while(iter.hasNext()) {
			Map product = (Map) iter.next();
			tempMap.put(product.get("product_id")+"", product.get("advance_price"));
		}
		System.err.println(tempMap);
		List items = advancePayDao.findAdvanceOrderItemsById(orderId);
		System.err.println(items);
		iter = items.iterator();
		while(iter.hasNext()) {
			Map item = (Map) iter.next();
			item.put("advance_price", tempMap.get(item.get("product_id")+""));
			item.put("unit_display", Unit4SaveEnum.getEnumByCode(Tool.toInt(item.get("unit"))).getName());
		}
		List pays = advancePayDao.findAdvancePaysById(orderId);
		Map advance = advancePayDao.findAdvanceByOrderId(orderId);
		return Maps.newHashMap("customer", customer, "items", items, "pays", pays, "advance", advance);
	}

}
